package routers

import (
	"fmt"
	"net/http"
	"strconv"

	"github.com/labstack/echo"
	"shqsoft.cn/pas3ui/base"
)

type JfData struct {
	NFYF          string         `json:"nfyf"`
	ZtZyCurrVal   float64        `json:"ztZyCurrVal"`
	ZtZyQntqVal   float64        `json:"ztZyQntqVal"`
	JxedCurrVal   float64        `json:"jxedCurrVal"`
	JxedQntqVal   float64        `json:"jxedQntqVal"`
	FyedCurrVal   float64        `json:"fyedCurrVal"`
	FyedQntqVal   float64        `json:"fyedQntqVal"`
	ZhZhZt        float64        `json:"zhZhZt"`
	ZhZhFy        float64        `json:"ztZyFy"`
	ZhZhJx        float64        `json:"zhZhJx"`
	ZhZhZtQn      float64        `json:"zhZhZtQn"`
	ZhZhFyQn      float64        `json:"ztZyFyQn"`
	ZhZhJxQn      float64        `json:"zhZhJxQn"`
	ZhzhZyDatas   []ZhzhZyData   `json:"zhzhZyDatas"`
	FhSyZyDatas   []FhSyZyData   `json:"fhSyZyDatas"`
	DeptJfDatas   []DeptJfData   `json:"deptJfDatas"`
	RelationDatas []RelationData `json:"relationDatas"`
	ZyZhAndSys    []ZyZhAndSy    `json:"zyZhAndSys"`
}
type ZhzhZyData struct {
	LB  string  `json:"lb"`
	YS  float64 `json:"ys"`
	HD  float64 `json:"hd"`
	ZXL float64 `json:"zxl"`
}
type FhSyZyData struct {
	LB string  `json:"lb"`
	JX float64 `json:"jx"`
	Fy float64 `json:"fy"`
}
type DeptJfData struct {
	DPID        int     `json:"dpid"`
	DPTP        string  `json:"dptp"`
	DPNM        string  `json:"dpnm"`
	ZtZyCurrVal float64 `json:"ztZyCurrVal"`
	ZtZyQntqVal float64 `json:"ztZyQntqVal"`
	ZtZyZl      float64 `json:"ztZyZl"`
	ZtZyZf      float64 `json:"ztZyZf"`
	JxedCurrVal float64 `json:"jxedCurrVal"`
	JxedQntqVal float64 `json:"jxedQntqVal"`
	JxedZl      float64 `json:"jxedZl"`
	JxedZf      float64 `json:"jxedZf"`
	FyedCurrVal float64 `json:"fyedCurrVal"`
	FyedQntqVal float64 `json:"fyedQntqVal"`
	FyedZl      float64 `json:"fyedZl"`
	FyedZf      float64 `json:"fyedZf"`
	KPI         float64 `json:"kpi"`
	ZyHbl       float64 `json:"zyHbl"`
	DC          int     `json:"dC"`
}
type RelationData struct {
	ID          string   `json:"id"`
	Name        string   `json:"name"`
	TxName      string   `json:"txName"`
	Level       uint8    `json:"level"`
	IsLeaf      bool     `json:"isLeaf"`
	ChildrenNum uint8    `json:"childrenNum"`
	YSJX        float64  `json:"ysjx"`
	YSFY        float64  `json:"ysfy"`
	YSHJ        float64  `json:"yshj"`
	HSJX        float64  `json:"hsjx"`
	HSFY        float64  `json:"hsfy"`
	HSHJ        float64  `json:"hshj"`
	ZXLJX       float64  `json:"zxljx"`
	ZXLFY       float64  `json:"zxlfy"`
	ZXLHJ       float64  `json:"zxlhj"`
	Tag         string   `json:"tag"`
	Tags        []string `json:"tags"`
}
type ZyZhAndSy struct {
	NFYF string  `json:"nfyf"`
	ZHJX float64 `json:"zhjx"`
	ZHFY float64 `json:"zhfy"`
	ZHHJ float64 `json:"zhhj"`
	SYJX float64 `json:"syjx"`
	SYFY float64 `json:"syfy"`
	SYHJ float64 `json:"syhj"`
}

func getJfData(year int, month int) (data JfData, err error) {
	var year2, month2 int
	sqlStr := `select max(NF),max(YF) from T_BASE_JHCW_JXFY_TX_ZXQK`
	row := base.MYDB.Raw(sqlStr).Row()
	err = row.Scan(&year2, &month2)
	if err != nil {
		return
	}
	if year == 0 {
		year = year2
		month = month2
	} else {
		if year*100+month > year2*100+month2 {
			err = fmt.Errorf("查询时间不能大于当前数据日期%d年%d月", year2, month2)
			return
		} else if year*100+month < 202403 {
			err = fmt.Errorf("查询时间不能小于2024年3月")
			return
		}
	}
	data.NFYF = strconv.Itoa(year) + "/" + strconv.Itoa(month) + "/1"
	jd := 0
	if month == 1 || month == 2 || month == 3 || month == 4 || month == 5 {
		jd = 1
	} else if month == 6 || month == 7 || month == 8 {
		jd = 2
	} else if month == 9 || month == 10 || month == 11 {
		jd = 3
	} else {
		jd = 4
	}
	//总行挣回
	sqlStr = "select LB,YS/10000,HD/10000,ZXL from T_BASE_JHCW_JXFY_ZHZY where NF=? AND JD=? group by LB"
	rows2, err := base.MYDB.Raw(sqlStr, year, jd).Rows()
	if err != nil {
		return
	}
	defer rows2.Close()
	zhDatas := make([]ZhzhZyData, 0, 5)
	for rows2.Next() {
		var zhData ZhzhZyData
		err = rows2.Scan(&zhData.LB, &zhData.YS, &zhData.HD, &zhData.ZXL)
		if err != nil {
			return
		}
		if zhData.LB == "费用" {
			data.ZhZhFy += zhData.HD
		} else {
			data.ZhZhJx += zhData.HD
		}
		zhDatas = append(zhDatas, zhData)
	}
	data.ZhzhZyDatas = zhDatas
	data.ZhZhZt = data.ZhZhFy + data.ZhZhJx
	sqlStr = "select LB,HD/10000 from T_BASE_JHCW_JXFY_ZHZY where NF=? AND JD=? group by LB"
	rows4, err := base.MYDB.Raw(sqlStr, year-1, jd).Rows()
	if err != nil {
		return
	}
	defer rows4.Close()
	for rows4.Next() {
		var lb string
		var hd float64
		err = rows4.Scan(&lb, &hd)
		if lb == "费用" {
			data.ZhZhFyQn += hd
		} else {
			data.ZhZhJxQn += hd
		}
	}
	data.ZhZhZtQn = data.ZhZhFyQn + data.ZhZhJxQn
	//分行使用
	sqlStr = "select JYDW1,sum(YJJX),sum(YXED) from T_BASE_JHCW_JXFY where NF=? and YF<=? group by JYDW1"
	rows5, err := base.MYDB.Raw(sqlStr, year, month).Rows()
	if err != nil {
		return
	}
	defer rows5.Close()
	fhDatas := make([]FhSyZyData, 0, 5)
	for rows5.Next() {
		var fhData FhSyZyData
		err = rows5.Scan(&fhData.LB, &fhData.JX, &fhData.Fy)
		if err != nil {
			return
		}
		fhDatas = append(fhDatas, fhData)
	}
	data.FhSyZyDatas = fhDatas

	sqlStr = `select RQ,JXZH,FYZH,ZZYZH,JXSY,FYSY,ZZYSY from T_BASE_JHCW_JXFY_ZHSY WHERE NF=? order by RQ`
	rows3, err := base.MYDB.Raw(sqlStr, year).Rows()
	if err != nil {
		return
	}
	defer rows3.Close()
	zsDatas := make([]ZyZhAndSy, 0, 5)
	for rows3.Next() {
		var zsData ZyZhAndSy
		err = rows3.Scan(&zsData.NFYF, &zsData.ZHJX, &zsData.ZHFY, &zsData.ZHHJ, &zsData.SYJX, &zsData.SYFY, &zsData.SYHJ)
		if err != nil {
			return
		}
		zsDatas = append(zsDatas, zsData)
	}
	data.ZyZhAndSys = zsDatas
	sqlStr = "select sum(YJJX)/10000,sum(YXED)/10000 from T_BASE_JHCW_JXFY where NF=? and YF<=?"
	row = base.MYDB.Raw(sqlStr, year, month).Row()
	err = row.Scan(&data.JxedCurrVal, &data.FyedCurrVal)
	if err != nil {
		return
	}
	sqlStr = "select sum(YJJX)/10000,sum(YXED)/10000 from T_BASE_JHCW_JXFY where NF=? and YF<=?"
	row = base.MYDB.Raw(sqlStr, year-1, month).Row()
	err = row.Scan(&data.JxedQntqVal, &data.FyedQntqVal)
	if err != nil {
		return
	}
	data.ZtZyCurrVal = data.JxedCurrVal + data.FyedCurrVal
	data.ZtZyQntqVal = data.JxedQntqVal + data.FyedQntqVal
	sqlStr = `select a.DPID,a.JYDW1,a.JYDW3,a.JX DQJX,a.FY DQFY,b.JX QYJX,b.FY QYFY,ifnull(c.DF,60) KPI,ifnull(c.DC, 3) DC
	from (select DPID,JYDW1,JYDW3,sum(YJJX)/10000 JX,sum(YXED)/10000 FY
		from T_BASE_JHCW_JXFY
		where NF=? AND YF<=?
		group by DPID,JYDW1,JYDW3) a left join
		(select DPID,JYDW3,sum(YJJX)/10000 JX,sum(YXED)/10000 FY
		from T_BASE_JHCW_JXFY
		where NF=? AND YF<=?
		group by DPID,JYDW3) b on a.DPID=b.DPID left join
		(select DPID,DF,DC
		from T_BASE_JHCW_JXFY_DEPT_KPI
		where NF=? AND JD=?) c on a.DPID=c.DPID`
	rows, err := base.MYDB.Raw(sqlStr, year, month, year-1, month, year, jd).Rows()
	if err != nil {
		return
	}
	defer rows.Close()
	jdDatas := make([]DeptJfData, 0, 20)
	for rows.Next() {
		var dpid, dc int
		var dptp, dpnm string
		var dqjx, qyjx, dqfy, qyfy, kpi float64
		err = rows.Scan(&dpid, &dptp, &dpnm, &dqjx, &qyjx, &dqfy, &qyfy, &kpi, &dc)
		if err != nil {
			return
		}
		d := DeptJfData{
			DPID:        dpid,
			DPTP:        dptp,
			DPNM:        dpnm,
			ZtZyCurrVal: dqjx + dqfy,
			ZtZyQntqVal: qyjx + qyfy,
			ZtZyZl:      dqjx + dqfy - (qyjx + qyfy),
			JxedCurrVal: dqjx,
			JxedQntqVal: qyjx,
			JxedZl:      dqjx - qyjx,
			FyedCurrVal: dqfy,
			FyedQntqVal: qyfy,
			FyedZl:      dqfy - qyfy,
			KPI:         kpi,
			DC:          dc,
		}
		if d.FyedQntqVal == 0 {
			d.FyedZf = 0
		} else {
			d.FyedZf = d.FyedZl / d.FyedQntqVal
		}
		if d.JxedQntqVal == 0 {
			d.JxedZf = 0
		} else {
			d.JxedZf = d.JxedZl / d.JxedQntqVal
		}
		if d.ZtZyQntqVal == 0 {
			d.ZtZyZf = 0
		} else {
			d.ZtZyZf = d.ZtZyZl / d.ZtZyQntqVal
		}
		if d.ZtZyCurrVal == 0 {
			d.ZyHbl = 0
		} else {
			d.ZyHbl = d.KPI / d.ZtZyCurrVal
		}
		jdDatas = append(jdDatas, d)
	}
	sqlStr = `select TX,YWLB,LJYSJX/10000,LJYSFY/10000,LJYSHJ/10000,LJHSJX/10000,LJHSFY/10000,LJHSHJ/10000,ROW_NUMBER() OVER(ORDER BY TX,YWLB) ID
	from T_BASE_JHCW_JXFY_TX_ZXQK
	where NF=? AND YF=?`
	rows, err = base.MYDB.Raw(sqlStr, year, month).Rows()
	if err != nil {
		return
	}
	defer rows.Close()
	rdatas := make([]RelationData, 0, 20)
	preTX := ""
	var ptag string
	pid := 0
	var prd *RelationData
	for rows.Next() {
		var id, tx, ywlb string
		var ljysjx, ljysfy, ljyshj, ljhsjx, ljhsfy, ljhshj float64
		err = rows.Scan(&tx, &ywlb, &ljysjx, &ljysfy, &ljyshj, &ljhsjx, &ljhsfy, &ljhshj, &id)
		if err != nil {
			return
		}
		if tx != preTX {
			if prd != nil {
				if prd.YSJX == 0 {
					prd.ZXLJX = 0
				} else {
					prd.ZXLJX = prd.HSJX / prd.YSJX
				}
				if prd.YSFY == 0 {
					prd.ZXLFY = 0
				} else {
					prd.ZXLFY = prd.HSFY / prd.YSFY
				}
				if prd.YSHJ == 0 {
					prd.ZXLHJ = 0
				} else {
					prd.ZXLHJ = prd.HSHJ / prd.YSHJ
				}
				rdatas = append(rdatas, *prd)
			}
			pid++
			ptag = "p" + strconv.Itoa(pid)
			prd = &RelationData{
				ID:          ptag,
				Name:        tx,
				Level:       0,
				ChildrenNum: 1,
				YSJX:        ljysjx,
				YSFY:        ljysfy,
				YSHJ:        ljyshj,
				HSJX:        ljhsjx,
				HSFY:        ljhsfy,
				HSHJ:        ljhshj,
				Tag:         ptag,
			}
		} else {
			prd.ChildrenNum++
			prd.YSJX += ljysjx
			prd.YSFY += ljysfy
			prd.YSHJ += ljyshj
			prd.HSJX += ljhsjx
			prd.HSFY += ljhsfy
			prd.HSHJ += ljhshj
		}
		rdata := RelationData{
			ID:          id,
			Name:        ywlb,
			TxName:      tx,
			Level:       1,
			ChildrenNum: 0,
			IsLeaf:      true,
			YSJX:        ljysjx,
			YSFY:        ljysfy,
			YSHJ:        ljyshj,
			HSJX:        ljhsjx,
			HSFY:        ljhsfy,
			HSHJ:        ljhshj,
			Tag:         id,
			Tags:        []string{ptag},
		}
		if rdata.YSJX == 0 {
			rdata.ZXLJX = 0
		} else {
			rdata.ZXLJX = rdata.HSJX / rdata.YSJX
		}
		if rdata.YSFY == 0 {
			rdata.ZXLFY = 0
		} else {
			rdata.ZXLFY = rdata.HSFY / rdata.YSFY
		}
		if rdata.YSHJ == 0 {
			rdata.ZXLHJ = 0
		} else {
			rdata.ZXLHJ = rdata.HSHJ / rdata.YSHJ
		}
		rdatas = append(rdatas, rdata)
		preTX = tx
	}
	data.DeptJfDatas = jdDatas
	data.RelationDatas = rdatas
	return
}

// JfDataRouter 获取绩效和费用数据（目前没有考虑权限）
func JfDataRouter(c echo.Context) (err error) {
	yearStr := c.Param("ny")
	year := 0
	month := 0
	if yearStr != "default" {
		year, err = strconv.Atoi(yearStr[0:4])
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, "年份参数无效："+err.Error())
		}
		month, err = strconv.Atoi(yearStr[5:7])
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, "月份参数无效："+err.Error())
		}
	}
	data, err := getJfData(year, month)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, data)
}
